#include <stdio.h>
#include <stdlib.h>
#include "algorithm.h"

/**
 * @brief  算法接口
 * @param  input            输入参数
 * @param  output           输出参数
 * @return int32_t          返回成功或者失败，RETURN_OK 或 RETURN_ERROR
 */
 static int mintime=0x7fffffff;
int32_t dfs(int32_t vis[],OutputParam *q,const InputParam *input, OutputParam *output){

    if (q->len==input->ioVec.len){
        AccessTime accessTime = {0};
        TotalAccessTime(input, q, &accessTime);
        if (accessTime.addressDuration<mintime){
            mintime=accessTime.addressDuration;
            for(int i=0;i<input->ioVec.len;i++){
                output->sequence[i]=q->sequence[i];
            }
            output->len=input->ioVec.len;
        }
        return mintime;
    }
    for(int i=0;i<input->ioVec.len;i++){
        if (!vis[i]){
            q->sequence[q->len++]=input->ioVec.ioArray[i].id;
            vis[i]=1;
            dfs(vis,q,input,output);
            vis[i]=0;
            q->len--;
        }
    }
    return mintime;
}
int32_t IOScheduleAlgorithm(const InputParam *input, OutputParam *output)
{
    int32_t ret;

    /* 算法示例：先入先出算法 */
    int32_t* vis=(int32_t *)malloc(input->ioVec.len*sizeof(int32_t));
    for(int i=0;i<input->ioVec.len;i++) vis[i]=0;
    OutputParam *q = (OutputParam *)malloc(sizeof(OutputParam));
    q->len=0;
    q->sequence=(uint32_t *)malloc(input->ioVec.len*sizeof(uint32_t));
    int32_t mintime=dfs(vis,q,input,output);
    /*printf("\t%d ms\n",mintime);
    printf("%d\n",output->len);
    for(int i=0;i<output->len;i++){
        printf("\t%d",output->sequence[i]);
    }
    printf("\n");
    /*HeadInfo end = {input->ioVec.ioArray[0].wrap, input->ioVec.ioArray[0].startLpos, HEAD_RW};
    printf("\t%d ms\n",SeekTimeCalculate(&(input->headInfo),&end));
    */
    /*int32_t seekT = 0, beltW = 0, motorW = 0,seekt=0;
    for(int i=0;i<output->len;i++){
        HeadInfo start;
        
            if  (i==0) start=input->headInfo;
            else {
                start.wrap=input->ioVec.ioArray[output->sequence[i-1]-1].wrap;
                start.lpos= input->ioVec.ioArray[output->sequence[i-1]-1].endLpos;
                start.status= HEAD_RW;
            }   
        HeadInfo end = {input->ioVec.ioArray[output->sequence[i]].wrap, input->ioVec.ioArray[output->sequence[i]].startLpos, HEAD_RW};
        
        seekt = SeekTimeCalculate(&start, &end);
        beltW = BeltWearTimes(&start, &end, NULL);
        motorW = MotorWearTimes(&start, &end);
        printf("\t%d:%d ms %d %d\n",output->sequence[i],seekt,beltW,motorW);
        AccessTime accessTime = {0};
        OutputParam *o1 = (OutputParam *)malloc(sizeof(OutputParam));
        o1->len =1;
        o1->sequence = (uint32_t *)malloc(output->len * sizeof(uint32_t));
        o1->sequence[0]=1;
        InputParam *in1=(InputParam *)malloc(sizeof(InputParam));
        in1->headInfo=start;
        in1->ioVec.len=1;
        in1->ioVec.ioArray=(IOUint *)malloc(in1->ioVec.len*sizeof(IOUint));
        in1->ioVec.ioArray[0]=input->ioVec.ioArray[output->sequence[i]-1];
        in1->ioVec.ioArray[0].id=1;
        TotalAccessTime(in1, o1, &accessTime);
        printf("\t%d:%d ms\n",output->sequence[i],accessTime.addressDuration);
        seekT+=accessTime.addressDuration;
        free(o1->sequence);
        free(o1);
        free(in1->ioVec.ioArray);
        free(in1);
    }
    printf("\ttotal:%d ms\n",seekT);
    /* 调用公共函数示例：调用电机寻址、带体磨损、电机磨损函数 
    HeadInfo start = {input->ioVec.ioArray[0].wrap, input->ioVec.ioArray[0].endLpos, HEAD_RW};
    HeadInfo end = {input->ioVec.ioArray[1].wrap, input->ioVec.ioArray[1].endLpos, HEAD_RW};
    int32_t seekT = 0;
    int32_t beltW = 0;
    int32_t motorW = 0;
       for (uint32_t i = 0; i < 10000; i++) {
           seekT = SeekTimeCalculate(&start, &end);
           beltW = BeltWearTimes(&start, &end, NULL);
           motorW = MotorWearTimes(&start, &end);
       }
*/
    /* 调用公共函数示例：调用IO读写时间函数 
    uint32_t rwT = ReadTimeCalculate(abs(input->ioVec.ioArray[0].endLpos - input->ioVec.ioArray[0].startLpos));
*/
    free(vis);
    free(q->sequence);
    free(q);
    return RETURN_OK;
}

/**
 * @brief  算法运行的主入口
 * @param  input            输入参数
 * @param  output           输出参数
 * @return uint32_t          返回成功或者失败，RETURN_OK 或 RETURN_ERROR
 */
int32_t AlgorithmRun(const InputParam *input, OutputParam *output)
{
    int32_t ret;

    ret = IOScheduleAlgorithm(input, output);
    return RETURN_OK;
}
